#
# This file is a part of the open-eBackup project.
# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
# If a copy of the MPL was not distributed with this file, You can obtain one at
# http://mozilla.org/MPL/2.0/.
#
# Copyright (c) [2024] Huawei Technologies Co.,Ltd.
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#

from typing import List

from pydantic import BaseModel, Field

from common.const import SubJobTypeEnum, SubJobPolicyEnum
from oracle.common.constants import DataBaseRole


class Node(BaseModel):
    id: str = Field(default=None, description='id')
    name: str = Field(default=None, description='name')
    type: str = Field(default=None, description='type')
    sub_type: str = Field(default=None, description='subType', alias='subType')
    endpoint: str = Field(default=None, description='endpoint')
    role: int = Field(default=1, description='role')
    extend_info: dict = Field(None, description='extend_info', alias='extendInfo')


class DBInfo(BaseModel):
    db_id: str = Field(default=None, description='db_id')
    db_unique_name: str = Field(default=None, description='db_unique_name')
    log_mode: str = Field(default=None, description='log_mode')
    open_mode: str = Field(default=None, description='open_mode', alias='open_mode')
    incarnation: str = Field(default=None, description='incarnation')
    resetlogs_id: str = Field(default=None, description='resetlogs_id')
    database_role: str = Field(default=None, description='database_role')
    current_scn: str = Field(default=None, description='current_scn')
    cdb: str = Field(default=None, description="cdb")
    inst_name: str = Field(default=None, description='inst_name')
    status: str = Field(default=None, description='status')

    @property
    def is_primary(self):
        return self.database_role == DataBaseRole.PRIMARY

    def is_same_database(self, param_name):
        return self.db_unique_name.lower() == str(param_name).lower()

    @property
    def can_backup(self):
        if self.is_primary:
            return self.status == 'OPEN'
        else:
            return self.status == 'MOUNTED' or self.status == "OPEN"

    @property
    def is_dg(self):
        return self.status == 'MOUNTED' and not self.is_primary


class InstanceInfo(BaseModel):
    instance_name: str = Field(default=None, description='instance_name')
    status: str = Field(default=None, description='status')
    version: str = Field(default=None, description="version")

    @property
    def major_version(self):
        return self.version[0:2]

    @property
    def is_11g(self):
        return int(self.major_version) == 11

    @property
    def is_support_cdb(self):
        return int(self.major_version) > 11

    @property
    def is_19c(self):
        return int(self.major_version) == 19


class QueryClusterResponse(BaseModel):
    id: str = Field(None, description='id')
    name: str = Field(None, description='name')
    type: str = Field(None, description='type')
    sub_type: str = Field(default=None, description='subType', alias='subType')
    endpoint: str = Field(None, description='endpoint')
    role: int = Field(default=1, description='role')
    extend_info: dict = Field(None, description='extend_info', alias='extendInfo')
    nodes: List[Node] = Field(None, description='node info')


class Resource(BaseModel):
    id: str = Field(default=None, description='id')
    name: str = Field(default=None, description='name')
    type: str = Field(default=None, description='type')
    sub_type: str = Field(default=None, description='subType', alias='subType')
    parent_id: str = Field(default=None, description='parentId', alias='parentId')
    parent_name: str = Field(default=None, description='parentName', alias='parentName')
    extend_info: dict = Field(None, description='extend_info', alias='extendInfo')


class ListAppResponse(BaseModel):
    resource_list: List[Resource] = Field(default=[], description='resource list', alias='resourceList')


class PermissionInfo(BaseModel):
    user: str = Field(default='oracle', description='user')
    group: str = Field(default='oinstall', description='group')
    file_mode: str = Field(default='0750', description='mod', alias='fileMode')


class BackupProgressInfo(BaseModel):
    s_time: int = Field(None, description="start_time", alias="s_time")
    c_time: int = Field(None, description="current_time", alias="c_time")
    status: int = Field(None, description="task_status", alias="status")
    error_code: int = Field(None, description="error_code", alias="error_code")
    message: str = Field(None, description="detail_info", alias="message")


class SubJob(BaseModel):
    job_id: str = Field(default='', description='jonId', alias='jobId')
    sub_job_id: str = Field(default='', description='subJobId', alias='subJobId')
    job_type: str = Field(default=SubJobTypeEnum.BUSINESS_SUB_JOB.value, description='jobType', alias='jobType')
    job_name: str = Field(default='', description='jobName', alias='jobName')
    job_priority: int = Field(default=1, description='jobPriority', alias='jobPriority')
    policy: int = Field(default=SubJobPolicyEnum.FIXED_NODE.value, description='policy')
    ignore_failed: bool = Field(default=False, description='ignoreFailed', alias='ignoreFailed')
    exec_node_id: str = Field(default='', description='execNodeId', alias='execNodeId')
    job_info: str = Field(default='', description='jobInfo', alias='jobInfo')


class OracleDiskInfo(BaseModel):
    disk_path: str = Field(default='', description='diskPath')
    wwn: str = Field(default='', description='wwn')
    num: str = Field(default='', description='num')


class PDBInfo(BaseModel):
    name: str = Field(default=None, description='name')
    open_mode: str = Field(default=None, description='open_mode')


class SCNAndTime(BaseModel):
    scn: str = Field(default=None, description='scn')
    time: str = Field(default=None, description='time')


class DBFile(BaseModel):
    con_id: str = Field(default='', description='con_id')
    ts_name: str = Field(default='', description='ts_name')
    file_no: str = Field(default='', description='file_no')
    ts_file: str = Field(default='', description='ts_file')


class PDBRestoreInfo(BaseModel):
    pdb_name: str = Field(default='', description='pdb_name')
    guid: str = Field(default='', description='guid')
    datafile_list: list = Field(default=[], description='datafile_list')
    tempfile_list: list = Field(default=[], description='tempfile_list')